//
//  双端循环队列.swift
//  Swift-LeetCode
//
//  Created by 卢悦明 on 2024/1/26.
//

import UIKit

class CircleDeque<Q> {
    var elements: [Q] = [Q]()
    var headQ = 0
    var size: Int = 0
    let defaultValue: Q
    init(_ size: Int = 10, defaultValue: Q) {
        self.size = 0
        self.defaultValue = defaultValue
        elements = [Q](repeating: defaultValue, count: size)
    }
//   队列长度
    func count() -> Int {
        elements.count
    }
//  队列是否为空
    func isEmpty() -> Bool {
        size == 0
    }
    func clear() {
        elements = elements.map { i in
            defaultValue
        }
        size = 0
    }
//    (队头)入队
    func enQueueFront(elem: Q) {
        headQ = index(-1)
        elements[headQ] = elem
        size += 1
    }
    //    (队尾)入队
    func enQueueRear(elem: Q) {
        let index = index(size)
        elements[index] = elem
        size += 1
    }
//    (队头)出队
    func deQueueFront() -> Q? {
        if isEmpty() {
            return nil
        } else {
            let value = elements[headQ]
            elements[headQ] = defaultValue
            headQ = index(1)
            size -= 1
            if size == 0 {
                headQ = 0
            }
            return value
        }
    }
    //    (队尾)出队列
    func deQueueRear() -> Q? {
        if isEmpty() {
            return nil
        } else {
            let rearIndex = index(size-1)
            let value = elements[rearIndex]
            elements[rearIndex] = defaultValue
            size -= 1
            return value
        }
    }
//    队列头部元素
    func front() -> Q? {
        elements[headQ]
    }
    //    队列尾部元素
    func rear() -> Q? {
        elements[index(size - 1)]
    }
}

extension CircleDeque {
    
    private func index(_ index: Int) -> Int {
        let index = headQ + index
        if index < 0 {
            return index + elements.count
        } else {
            return index % elements.count
        }
    }
    
    /// 打印栈中的内容<从栈顶到尾部>
    func printQueue() {
        let elements = self.elements
        print("队列结构")
        var printStr = "头部 "
        var top = "————"
        for (index,elem) in elements.enumerated() {
            if index == headQ {
                printStr = printStr + "$\(elem)$ "
            } else {
                printStr = printStr + "\(elem) "
            }
            top = top + "——"
        }
        top = top + "————"
        printStr = printStr + "尾部"
        print(top)
        print(printStr)
        print(top)
    }
}
